return s.taboption(tabName, optionClass, optionName, optionTitle, optionDescription);
},
- addDeviceOptions: function(s, dev, isNew) {
+ addDeviceOptions: function(s, dev, isNew, rtTables) {
var parent_dev = dev ? dev.getParent() : null,
devname = dev ? dev.getName() : null,
o, ss;
s.tab('bridgevlan', _('Bridge VLAN filtering'));
o = this.replaceOption(s, 'devgeneral', form.ListValue, 'type', _('Device type'),
- !L.hasSystemFeature('bonding') && isNew ? '<a href="' + L.url("admin", "system", "package-manager", "?query=kmod-bonding") + '">'+
- _('For bonding, install %s').format('<code>kmod-bonding</code>') + '</a>' : null);
+ (!L.hasSystemFeature('bonding') && isNew ? '<a href="' + L.url("admin", "system", "package-manager", "?query=kmod-bonding") + '">'+
+ _('For bonding, install %s').format('<code>kmod-bonding</code>') + '</a><br/>' : '') +
+ (!L.hasSystemFeature('vrf') && isNew ? '<a href="' + L.url("admin", "system", "package-manager", "?query=kmod-vrf") + '">'+
+ _('For VRF, install %s').format('<code>kmod-vrf</code>') + '</a><br/>' : ''));
o.readonly = !isNew;
o.value('', _('Network device'));
if (L.hasSystemFeature('bonding')) {
o.value('8021ad', _('VLAN (802.1ad)'));
o.value('macvlan', _('MAC VLAN'));
o.value('veth', _('Virtual Ethernet'));
+ if (L.hasSystemFeature('vrf') && L.hasSystemFeature('netifd_vrf')) {
+ o.value('vrf', _('VRF device'));
+ }
o.validate = function(section_id, value) {
- if (value == 'bonding' || value == 'bridge' || value == 'veth')
+ if (value == 'bonding' || value == 'bridge' || value == 'veth' || value == 'vrf')
updatePlaceholders(this.section.getOption('name_complex'), section_id);
return true;
o.datatype = 'uinteger';
o.depends({'type': 'bonding', 'monitor_mode': 'mii'});
- o = this.replaceOption(s, 'devgeneral', widgets.DeviceSelect, 'ifname_multi-bridge', _('Bridge ports'));
+ o = this.replaceOption(s, 'devgeneral', widgets.DeviceSelect, 'ifname_multi-bridge', dev?.getType() == 'bridge' ? _('Bridge ports'): _('Ports'));
o.size = 10;
o.rmempty = true;
o.multiple = true;
return (!parent_dev || parent_dev.getName() != bridge_name);
};
- o.description = _('Specifies the wired ports to attach to this bridge. In order to attach wireless networks, choose the associated interface as network in the wireless settings.')
+ o.description = dev?.getType() == 'bridge' ? _('Specifies the wired ports to attach to this bridge. In order to attach wireless networks, choose the associated interface as network in the wireless settings.'):
+ _('Specifies the devices to attach to this VRF. In order to attach wireless networks, choose the associated interface as network in the wireless settings.');
o.onchange = function(ev, section_id, values) {
ss.updatePorts(values);
});
};
o.depends('type', 'bridge');
+ o.depends('type', 'vrf');
+
+ o = this.replaceOption(s, 'devgeneral', form.Value, 'table', _('Routing table'));
+ rtTables.forEach((rtTable) => {
+ o.value(rtTable[1], '%s (%d)'.format(rtTable[1], rtTable[0]));
+ })
+ o.depends('type', 'vrf');
o = this.replaceOption(s, 'devgeneral', form.Flag, 'bridge_empty', _('Bring up empty bridge'), _('Bring up the bridge interface even if no ports are attached'));
o.default = o.disabled;
var isNew = (uci.get('network', s.section, 'name') == null),
dev = getDevice(s.section);
- nettools.addDeviceOptions(s, dev, isNew);
+ nettools.addDeviceOptions(s, dev, isNew, rtTables);
};
s.handleModalCancel = function(map /*, ... */) {
case 'veth':
return 'veth';
+ case 'vrf':
+ return 'vrf';
+
case 'wifi':
case 'alias':
case 'switch':
case 'veth':
return _('Virtual Ethernet');
+ case 'vrf':
+ return _('Virtual Routing and Forwarding (VRF)');
+
default:
return _('Network device');
}
_('This prefix is randomly generated at first install.'));
o.datatype = 'cidr6';
+ const l3mdevhelp1 = _('%s services running on this device in the default VRF context (ie., not bound to any VRF device) shall work across all VRF domains.');
+ const l3mdevhelp2 = _('Off means VRF traffic will be handled exclusively by sockets bound to VRFs.');
+
+ o = s.option(form.Flag, 'tcp_l3mdev', _('TCP Layer 3 Master Device (tcp_l3mdev) accept'),
+ l3mdevhelp1.format('TCP') + '<br/>' +
+ l3mdevhelp2);
+
+ o = s.option(form.Flag, 'udp_l3mdev', _('UDP Layer 3 Master Device (udp_l3mdev) accept'),
+ l3mdevhelp1.format('UDP') + '<br/>' +
+ l3mdevhelp2);
+
o = s.option(form.ListValue, 'packet_steering', _('Packet Steering'), _('Enable packet steering across CPUs. May help or hinder network speed.'));
o.value('0', _('Disabled'));
o.value('1',_('Enabled'));